<?php

namespace LhpAmis\Traits;

use LhpAmis\Renderers\BaseRenderer;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use LhpAmis\Renderers\AjaxAction;
use LhpAmis\Renderers\Button;
use LhpAmis\Renderers\DialogAction;
use LhpAmis\Renderers\OtherAction;
use LhpAmis\Renderers\Service;
use LhpAmis\Renderers\Amis;

trait ButtonsTrait
{

    /**
     * 操作列
     *
     * @param  $dialog     是否弹窗, 弹窗: true|dialog, 抽屉: drawer
     * @param string $dialogSize 弹窗大小, 默认: md, 可选值: xs | sm | md | lg | xl | full
     *
     * @return \LhpAmis\Renderers\Operation
     */
    protected function rowActions($dialog = false, string $dialogSize = 'md')
    {
        if (is_array($dialog)) {
            return Amis::make()->Operation()->label('操作')->buttons($dialog);
        }

        $actions = Amis::make()->Operation()->label('操作')->buttons([
            $this->rowShowButton($dialog, $dialogSize),
            $this->rowEditButton($dialog, $dialogSize),
            $this->rowDeleteButton(),
        ]);

        return $actions;
    }

    /**
     * 返回列表按钮
     */
    protected function backButton(): OtherAction
    {
        return Amis::make()->OtherAction()
            ->label('返回')
            ->icon('fa-solid fa-chevron-left')
            ->level('primary')
            ->onClick('window.history.back();');
    }

    protected function LinkButton($title, $url, $icon = '', $level = '')
    {
        $title = $title ?: '链接';
        $action = $this->customButton($title, 'LinkAction', $icon, $level);
        $action->link($url);

        if (!$this->authAmis($action)) {
            return $action->disabled(true);
        }
        return $action;
    }
    protected function UrlButton($title, $url, $blank = true, $icon = '', $level = 'link')
    {
        $title = $title ?: '链接';
        $action = $this->customButton($title, 'UrlAction', $icon, $level);
        $action->url($url)->blank($blank);
        if (!$this->authAmis($action)) {
            return $action->disabled(true);
        }
        return $action;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    protected function AjaxFormButton(string $title = '', string $url = '', string $method = 'get', array $args = [], array $options = []): AjaxAction
    {
        return $this->AjaxButton($title, $url, $method, $args, $options);

    }

    /**
     * ajax按钮
     * @param string $title
     * @param string $url
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function DialogAjaxButton(string $title = '', string $url = '', string $method = 'get', array $args = [], array $data = [], array $options = [])
    {
        isset($args[$this->primaryKey]) ?: $args[$this->primaryKey] = '${' . $this->primaryKey . '}';

        $bottonAction = Amis::make()->AjaxAction()->label($title)->close(true)->primary(true)->api($this->amisBaseApi($url, $method, [$args], $data))
            ->feedback(['title' => '提示:', 'body' => '操作成功', 'actions' => [["type" => "button", "actionType" => "close", "label" => "关闭"]]]);

        $action = Amis::make()->DialogAction()->label($title)->dialog(
            Amis::make()->Dialog()->body(Amis::make()->Form())->title('确认是否' . $title)
                ->actions([$bottonAction])
        );

        foreach ($options as $key => $option) {
            //添加自定义参数，
            $action->$key($option);
        }
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }
    /**
     * ajax按钮
     * @param string $title
     * @param string $url
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function AjaxButton(string $title = '', string $url = '', string $method = 'get', array $args = [], array $data = [], array $options = []): AjaxAction
    {
        isset($args[$this->primaryKey]) ?: $args[$this->primaryKey] = '${' . $this->primaryKey . '}';

        $action = Amis::make()->AjaxAction()->label($title);

        $action->api($this->amisBaseApi($url, $method, [$args], $data))->level('link');
        foreach ($options as $key => $option) {
            //添加自定义参数，
            $action->$key($option);
        }
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }

    /**
     * 行自定义按钮
     *
     * @param string $title 弹窗标题 & 按钮文字, 默认: 新增
     *
     * @return \LhpAmis\Renderers\DialogAction|\LhpAmis\Renderers\LinkAction
     */
    /**
     * Summary of rowCustomButton
     * @param mixed $baseApi 接口地址
     * @param string $title 弹窗标题 & 按钮文字, 默认: 新增
     * @param mixed $dialogSize 弹窗大小
     * @param mixed $level 按钮类型
     * @return DialogAction
     */
    protected function rowCustomButton($baseApi = '', string $title = '', string $dialogSize = 'md', $level = 'link')
    {
        $title = $title ?: '自定义按钮';

        $urlPage = Amis::make()->Service()->schemaApi($baseApi);
        $action = Amis::make()->DialogAction()->dialog(
            Amis::make()->Dialog()->title($title)->body($urlPage)->size($dialogSize)->actions([])
        );

        $action->label($title)->level($level);
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }
    /**
     * 新增按钮
     *
     * @param  $dialog     是否弹窗, 弹窗: true|dialog, 抽屉: drawer,
     * @param string $title 弹窗标题 & 按钮文字, 默认: 新增
     *
     * @return \LhpAmis\Renderers\DialogAction|\LhpAmis\Renderers\LinkAction
     */
    protected function customButton(string $title = '', string $ActionName = '', $api = '', $icon = '', $level = 'primary')
    {
        $title = $title ?: '自定义按钮';

        $action = Amis::make()->$ActionName()->label($title);
        $action->label($title)->icon($icon)->level($level);
        if ($api !== '') {
            $action->api($api);
        }

        return $action;
    }
    /**
     * 行编辑按钮
     * @param string $title 弹窗标题 & 按钮文字, 默认: 编辑
     * @param string $dialogSize 弹窗大小, 默认: md, 可选值: xs | sm | md | lg | xl | full
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function schemaButton(string $title = '添加', $api = '', string $dialogSize = 'md'): DialogAction
    {
        $urlPage = Amis::make()->Service()->schemaApi($api);
        $action = Amis::make()->DialogAction()->dialog(
            Amis::make()->Dialog()->title($title)->body($urlPage)->size($dialogSize)->actions([])
        );

        $action->label($title)->level('success');
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }

    /**
     * 行编辑按钮
     * @param string $title 弹窗标题 & 按钮文字, 默认: 编辑
     * @param string $dialogSize 弹窗大小, 默认: md, 可选值: xs | sm | md | lg | xl | full
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function createButton(string $title = '添加', string $dialogSize = 'md'): DialogAction
    {
        $urlPage = Amis::make()->Service()->schemaApi($this->BaseApiGet('create', [$this->primaryKey => '${' . $this->primaryKey . '}']));
        $action = Amis::make()->DialogAction()->dialog(
            Amis::make()->Dialog()->title($title)->body($urlPage)->size($dialogSize)->actions([])
        );

        $action->label($title)->level('success');
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }

    /**
     * 行编辑按钮
     *
     * @param string $title 弹窗标题 & 按钮文字, 默认: 编辑
     *
     * @param string $dialogSize 弹窗大小, 默认: md, 可选值: xs | sm | md | lg | xl | full
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowEditerButton(string $title = '编辑', string $dialogSize = 'md'): DialogAction
    {
        $urlPage = Amis::make()->Service()->schemaApi($this->BaseApiGet('update', [$this->primaryKey => '${' . $this->primaryKey . '}']));
        $action = Amis::make()->DialogAction()->dialog(
            Amis::make()->Dialog()->title($title)->body($urlPage)->size($dialogSize)->actions([])
        );

        $action->label($title)->level('link');

        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }
    /**
     * 验证权限 自行实现AmisUserAuth函数
     * @param mixed $actionOrUrl
     * @return bool
     */
    protected function authAmis($actionOrUrl)
    {
        if (is_string($actionOrUrl)) {
            return function_exists('AmisUserAuth') ? AmisUserAuth($actionOrUrl) : true;
        }
        if ($actionOrUrl instanceof BaseRenderer) {
            $node = $this->extractUrlsFromJson($actionOrUrl);
            if (empty($node)) {
                return false;
            }
            return function_exists('AmisUserAuth') ? AmisUserAuth($node[0]) : true;
        }
        return false;

    }
    private function extractUrlsFromJson($data = [])
    {
        // 将数据转换为字符串以便进行正则匹配
        $dataString = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

        // 正则表达式匹配URL路径
        $pattern = '/https?:\/\/[^\s"]+|[a-zA-Z0-9\-._~:\/?#\[\]@!$&\'()*+,;=]+\/[^\s"]*/';
        preg_match_all($pattern, $dataString, $matches);

        // 返回匹配到的URL路径数组
        return $matches[0];
    }

    /**
     * 行删除按钮
     *
     * @param string $title
     * @param string $url
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowDeleteButton(string $title = '删除', array $args = ['id' => '${id|raw}'], array $options = []): AjaxAction
    {
        return $this->statusButton($title, 'delete', 'delete', $args, $options);

    }


    protected string $exportApi = 'export';


    /**
     * 行启用按钮
     *
     * @param string $title
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowEnableButton(string $title = '启用', array $args = ['id' => '${id|raw}'], $data = ['status' => 1], array $options = []): AjaxAction
    {
        return $this->statusButton($title, 'modify', 'post', $args, $data, $options);

    }


    /**
     * 行禁用按钮
     *
     * @param string $title
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowDisableButton(string $title = '禁用', array $args = ['id' => '${id|raw}'], $data = ['status' => 0], array $options = []): AjaxAction
    {

        return $this->statusButton($title, 'modify', 'post', $args, $data, $options);
    }

    /**
     * 批量启用按钮
     *
     * @param string $title
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function bulkEnableButton(string $title = '启用', array $args = ['id' => '${ids|raw}'], $data = ['status' => 1], array $options = []): AjaxAction
    {
        return $this->statusButton($title, 'modify', 'post', $args, $data, $options);

    }


    /**
     * 批量禁用按钮
     *
     * @param string $title
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function bulkDisableButton(string $title = '禁用', array $args = ['id' => '${ids|raw}'], $data = ['status' => 0], array $options = []): AjaxAction
    {

        return $this->statusButton($title, 'modify', 'post', $args, $data, $options);
    }

    /**
     * 行状态开关按钮
     *
     * @param string $title
     * @param string $url
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function statusButton(string $title = '', string $url = 'modify', string $method = 'post', array $args = [], array $data = [], array $options = []): AjaxAction
    {
        // isset($args['primaryKey']) ?$args: $args[$this->primaryKey] = '${' . $this->primaryKey . '}';
        $action = $this->AjaxButton($title, $url, $method, $args, $data, $options)->level('link')->confirmText('确认' . $title . '？');

        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }


    /**
     * @param string $url
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function bulkDeleteButton(string $title = '删除', string $method = 'delete', array $args = ['id' => '${ids|raw}', 'status' => 0], array $options = []): AjaxAction
    {

        return $this->statusButton($title, 'modify', $method, $args, $options);
    }




    /**
     * Summary of DialogIframeButton
     * @param string $title
     * @param mixed $url
     * @param string $dialogSize * Dialog 大小 可选值: xs | sm | md | lg | xl | full
     * @param mixed $icon
     * @return \LhpAmis\Renderers\DialogAction
     */
    protected function DialogIframeButton(string $title = '', $url = 'form', string $dialogSize = 'full', $icon = '', $level = 'primary')
    {
        $title = $title ?: '';

        $form = Amis::make()->IFrame()->src($url);
        $action = Amis::make()->DialogAction()->dialog(
            Amis::make()->Dialog()->title($title)->body($form)->size($dialogSize)->actions([])
        );

        $action->label($title)->level($level);
        if ($icon) {
            $action->icon(true);
        }
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }

    protected function DrawerButton(string $title = '', $formMonth = 'form', $url = 'form', string $dialogSize = 'md', $icon = '')
    {

        if (is_callable($formMonth)) {
            $form = call_user_func($formMonth);
        } else if (is_string($formMonth)) {
            $form = $this->$formMonth();
        } else {
            $form = $this->baseForm();
        }

        $form = $form->canAccessSuperData(false)->api(BaseApiPost($url))->onEvent([]);

        $action = Amis::make()->DrawerAction()->drawer(
            Amis::make()->Drawer()->title($title)->body($form)->size($dialogSize)
        );

        $action->label($title)->level('primary');
        if ($icon) {
            $action->icon(true);
        }
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }

    protected function DialogButton(string $title = '弹窗', $formMonth = 'form', string $dialogSize = 'md', $icon = '')
    {
        $title = $title ?: '';

        if (is_callable($formMonth)) {
            $form = call_user_func($formMonth);
        } else if (is_string($formMonth)) {
            $form = $this->$formMonth();
        } else {
            $form = $this->baseForm();
        }

        $action = Amis::make()->DialogAction()->dialog(
            Amis::make()->Dialog()->title($title)->body($form)->size($dialogSize)
                ->actions([Amis::make()->Button()->actionType('submit')->primary(true)->label($title)])
        );

        $action->label($title)->level('primary');
        if ($icon) {
            $action->icon(true);
        }
        if (!$this->authAmis($action)) {
            return $action->disabled();
        }
        return $action;
    }

    /**
     * 设置表单按钮
     * @param string $label 按钮名称
     * @param string $type 按钮类型
     * @param array $extend_attr 扩展属性
     * @return $this
     */
    protected function setActions($label = '', $type = '', $extend_attr = [])
    {
        $items = Amis::make()->Action()->label($label)->actionType($type);
        $this->extend_attr($items, $extend_attr);
        $this->actions[] = $items;
        return $this;
    }
}